﻿using System;

using System.Runtime.InteropServices;

namespace Eflong.Structure
{
    [Serializable]
    [StructLayout( LayoutKind.Sequential )]
    public struct LoginStruct
    {
        private const int SIZE_USERID = 17;
        private const int SIZE_PASSWORD = 9;
        private const int SIZE_MACADDRESS = 13;
        private const int SIZE_LICENSEKEY = 49;
        private const int SIZE_OPTIONS = 228;
        private const int SIZE_SYSTEMTIME = 16;

        public const int VCS_MT_LOGIN = 1;
        public const int VCS_MT_LOGOUT = 2;

        public const int LOGIN_BRIDGE = 1;
        public const int LOGOUT_BRIDGE = 2;
        public const int LOGIN_CLIENT = 3;
        public const int LOGOUT_CLIENT = 4;

        public const int VCS_MT_LOGIN_EX = VizClientServer.VCS_MT_LOGIN_EX;// 31;
        public const int VCS_MT_LOGOUT_EX = VizClientServer.VCS_MT_LOGOUT_EX;// 32;

        public const int LOGIN_BRIDGE_EX = 5;
        public const int LOGOUT_BRIDGE_EX = 6;
        public const int LOGIN_CLIENT_EX = 7;
        public const int LOGOUT_CLIENT_EX = 8;

        public const int LOGIN_NETWORKMODE = 0;
        public const int LOGIN_TYPE = LOGIN_CLIENT;

        public uint m_dwMethodType;
        public int m_nMethodAck;

        [MarshalAs( UnmanagedType.ByValTStr , SizeConst = SIZE_USERID )]
        public string m_szUserId;

        [MarshalAs( UnmanagedType.ByValTStr , SizeConst = SIZE_PASSWORD )]
        public string m_szPassword;

        public int m_nType;
        public uint m_dwPermission;

        //Options m_Options;
        [MarshalAs( UnmanagedType.ByValArray , SizeConst = SIZE_OPTIONS )]
        public char[ ] m_Options;

        ///SYSTEMTIME m_stServer;
        //[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIZE_SYSTEMTIME)]
        public SystemTime m_stServer;

        [MarshalAs( UnmanagedType.ByValTStr , SizeConst = SIZE_MACADDRESS )]
        public string m_szMACAddress;

        [MarshalAs( UnmanagedType.ByValTStr , SizeConst = SIZE_LICENSEKEY )]
        public string m_szLicenseKey;

        public LoginStruct( string userId , string password , uint dwMethodType , int nType , uint dwPermission )
        {
            m_Options = new char[ SIZE_OPTIONS ];
            m_stServer = new SystemTime( );

            m_dwMethodType = dwMethodType;
            m_nMethodAck = 0;
            m_nType = nType;
            m_dwPermission = dwPermission;
            m_szUserId = userId;
            m_szPassword = password;

            m_szMACAddress = string.Empty;
            m_szLicenseKey = string.Empty;
        }

        public byte[ ] GetByteArray( )
        {
            byte[ ] ba = new byte[ Marshal.SizeOf( this ) ];
            IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement( ba , 0 );
            Marshal.StructureToPtr( this , ptr , true );
            return ba;
        }

        public static LoginStruct ConverFromByteArray( byte[ ] ba )
        {
            GCHandle pinnedPacket = GCHandle.Alloc( ba , GCHandleType.Pinned );

            LoginStruct vcs = ( LoginStruct )Marshal.PtrToStructure(
                pinnedPacket.AddrOfPinnedObject( ) ,
                typeof( LoginStruct ) );
            pinnedPacket.Free( );
            return vcs;
        }

        public int length( )
        {
            return Marshal.SizeOf( this );
        }
    }
}